package org.mte.sak.sort;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.mte.sak.reflect.ReflectHandler;
import org.mte.sak.sort.comparator.Comparator;
import org.mte.sak.sort.comparator.ComparatorFactory;

/**
 * AbstractSort
 *
 * @author Marco Traversari
 * @version $Revision: 1.1 $ $Date: 2011-04-18 08:38:00 $ $Author: marco $
 */
public abstract class AbstractSort implements Sortable {

	   /**
     * The sort function.
     *
     * @param keys the array with all keys.
     * @param objs the array with all objects.
     * @param start the start offset in the array.
     * @param end the end offset in the array.
     * @param comp The comparaison function between objects.
     */
	public abstract void sort(Object[] keys, Object[] objs, int start, int end, Comparator comp);

	/**
     * The sort function.
     *
     * @param keys the array with all keys.
     * @param objs the array with all objects.
     * @param comp The comparaison function between objects.
     */
	public abstract void sort(Object[] keys, Object[] objs, Comparator comp);
	
	/**
	 * sort
	 * @param <E>
	 * @param aKeys
	 * @param aObjs
	 * @param comp
	 */
	@SuppressWarnings("unchecked")
	public <E> void sort(ArrayList<E> aKeys, ArrayList<E> aObjs, Comparator comp) {
		int size = aKeys.size();
		Object[] keys = new Object[size]; 
		Object[] objs = new Object[size];
		int k = 0;
		for (Object aKey : aKeys) {
			keys[k] = aKey;
			k++;
		}
		int o = 0;
		for (Object aObj : aObjs) {
			objs[o] = aObj;
			o++;
		}
		sort(keys, objs, comp);
		aObjs.clear();
		for (Object obj : objs) {
			aObjs.add((E) obj);
		}
	}

	/**
	 * sort
	 * @param list
	 * @param methodName
	 * @param isAscending
	 * @param Exception
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void sort(List list, String methodName, boolean isAscending) throws Exception {
		int size = list.size();
		Object[] keys = new Object[size];
		Object[] objs = new Object[size];
		ReflectHandler rf0 = new ReflectHandler(list.get(0));
		Object obj0 = rf0.invoke(methodName);
		Class c = obj0.getClass();
		Comparator comparator = ComparatorFactory.getComparator(c.getName());
	    comparator.setAscending(isAscending);
	    Iterator<?> iterator = list.iterator();
	    int i = 0;
	    while (iterator.hasNext()) {
	    	Object object = iterator.next();
	    	ReflectHandler rf = new ReflectHandler(object);
	    	keys[i] = rf.invoke(methodName);
	    	objs[i] = object;
	    	i++;
	    }
	    sort(keys, objs, comparator);
	    list.clear();
	    for (Object obj : objs) {
	    	list.add(obj);
	    }
	}
}
